%{ open Ast %}

//      (       )      {     }        [       ]     ;      ,
%token LPAREN RPAREN LBRACE RBRACE LSBRACE RSBRACE SEMI COMMA 
//        ++         --
%token PLUSPLUS MINUSMINUS
//     == != <  <= >  >=
%token EQ NE LT LE GT GE
//      && ||  !  .
%token AND OR NOT DOT
//      +     -     *      /    %
%token PLUS MINUS TIMES DEVIDE MOD
//       =      +=              -=          *=         %=
%token ASSIGN PLUS_ASSIGN MINUS_ASSIGN TIMES_ASSIGN MOD_ASSIGN
//reserved keywords for control flow
%token RETURN IF ELSE FOR BREAK
//reserved keywords for types
%token INT DOUBLE STRING LIST POINT SHAPE IMAGE STRUCT
%token <string> ID
//constants
%token <int> CONST_INT
%token <float> CONST_DBL
%token <string> CONST_STR

%token EOF

/*
   The operator precedence is based on the following page:
   http://en.cppreference.com/w/cpp/language/operator_precedence
*/

%right ASSIGN PLUS_ASSIGN MINUS_ASSIGN TIMES_ASSIGN MOD_ASSIGN
%left OR
%left AND
%left EQ NE
%left LT GT LE GE
%left PLUS MINUS
%left TIMES DIVIDE MOD
%left DOT
%right NOT

%start program
%type <Ast.program> program

%%

program: 
/* type program = func_decl list * stmt list */
	/* nothing */ { [],[] }
	|program f_decl { ($2 :: fst $1), snd $1 }
	|program stmt   { fst $1, ($2 :: snd $1) }

